package com.b2b.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 版权：上海极和信息科技有限公司
 * 功能：工具类
 * 作者：朱伟峰
 * 邮箱：zhuweifeng24@gmail.com
 * 日期：2015年11月26日
 */
public class Tools
{
	private static final Logger logger = LoggerFactory.getLogger(Tools.class);
	
	public static String genNull(String str)
	{
		return str == null ? "" : str;
	}

	public static boolean isEmpty(String str)
	{
		return (str == null) || (str.equals(""));
	}

	public static boolean isTrimEmpty(String str)
	{
		return (str == null) || (str.equals("")) || (isEmpty(str.trim()));
	}
	
	public static String genString(Object value)
	{
		if (value == null)
			return null;
		else if (value instanceof String)
			return (String) value;
		else
			return value.toString();
	}
	
	public static String genString(Object value, String defaultValue)
	{
		if (value == null)
			return defaultValue;
		else if (value instanceof String)
			return (String) value;
		else
			return value.toString();
	}
	
	public static int genInt(String sValue)
	{
		return Tools.genInt(sValue, 0);
	}
	
	public static int genInt(String sValue, int defaultValue)
	{
		if (Tools.isEmpty(sValue))
		{
			return defaultValue;
		}
		
		try
		{
			return Integer.parseInt(sValue);
		}
		catch (Exception ex)
		{
			return defaultValue;
		}
	}

	public static int genInt(Object value)
	{
		if (value == null)
			return 0;
		else if (value instanceof Integer)
			return (int) value;
		else
			return Tools.genInt(value.toString());
	}
	
	public static long genLong(String sValue)
	{
		long lValue;
		try
		{
			lValue = Long.parseLong(sValue);
		}
		catch (Exception ex)
		{
			lValue = 0L;
		}

		return lValue;
	}
	
	public static long genLong(Object value)
	{
		if (value == null)
			return 0L;
		else if (value instanceof Long)
			return (long) value;
		else
			return Tools.genLong(value.toString());
	}
	
	public static short genShort(String sValue)
	{
		short iValue;
		try
		{
			iValue = Short.parseShort(sValue);
		}
		catch (Exception ex)
		{
			iValue = 0;
		}

		return iValue;
	}

	public static short genShort(Object value)
	{
		if (value == null)
			return 0;
		else if (value instanceof Short)
			return (short) value;
		else
			return Tools.genShort(value.toString());
	}
	
	public static byte genByte(String sValue)
	{
		byte bValue;
		try
		{
			bValue = Byte.parseByte(sValue);
		}
		catch (Exception ex)
		{
			bValue = 0;
		}

		return bValue;
	}

	public static byte genByte(Object value)
	{
		if (value == null)
			return (byte)0;
		else if (value instanceof Byte)
			return (byte) value;
		else
			return Tools.genByte(value.toString());
	}
	
	public static float genFloat(String sValue)
	{
		float fValue;
		try
		{
			fValue = Float.parseFloat(sValue);
		}
		catch (Exception ex)
		{
			fValue = 0.0F;
		}

		return fValue;
	}
	
	public static float genFloat(Object value)
	{
		if (value == null)
			return 0F;
		else if (value instanceof Float)
			return (float) value;
		else
			return Tools.genFloat(value.toString());
	}
	
	public static double genDouble(String sValue)
	{
		return Tools.genDouble(sValue, 0.0D);
	}
	
	public static double genDouble(String sValue, double defaultValue)
	{
		if (Tools.isEmpty(sValue))
		{
			return defaultValue;
		}
		
		try
		{
			return Double.parseDouble(sValue);
		}
		catch (Exception ex)
		{
			return defaultValue;
		}
	}

	public static double genDouble(Object value)
	{
		if (value == null)
			return 0D;
		else if (value instanceof Double)
			return (double) value;
		else
			return Tools.genDouble(value.toString());
	}
	
	public static Date genDate(String sValue, String sFormat)
	{
		Date dValue;
		try
		{
			if ((sFormat == null) || (sFormat.trim().equals("")))
			{
				sFormat = "yyyy-MM-dd HH:mm:ss";
			}
			SimpleDateFormat dateFormat = new SimpleDateFormat(sFormat);

			dValue = dateFormat.parse(sValue);
		}
		catch (Exception ex)
		{
			dValue = new Date(0L);
		}

		return dValue;
	}

	public static Date genDate(String sValue)
	{
		return genDate(sValue, "");
	}

	public static Date genJustDate(String sValue)
	{
		return genDate(sValue, "yyyy-MM-dd");
	}

	public static Date genDate(long lValue, String sFormat)
	{
		if ((sFormat == null) || (sFormat.trim().equals("")))
		{
			sFormat = "yyyy-MM-dd HH:mm:ss";
		}
		return genDate(formatDate(new Date(lValue), sFormat), sFormat);
	}

	public static long genLong(Date date)
	{
		if (date != null) { return date.getTime(); }
		return 0L;
	}

	public static Date genDate(long value)
	{
		if (value != 0L) { return genDate(value, ""); }
		return null;
	}

	public static Date genJustDate(long lValue)
	{
		return genDate(lValue, "yyyy-MM-dd");
	}

	public static double formatData(double fData, String sFormatString)
	{
		try
		{
			DecimalFormat df = new DecimalFormat(sFormatString);

			return Double.parseDouble(df.format(fData));
		}
		catch (NumberFormatException nfe)
		{
			logger.error("", nfe);
		}
		return 0.0D;
	}

	public static String formatDate(long lDate, String sFormat)
	{
		return formatDate(new Date(lDate), sFormat);
	}

	public static String formatDate(long lDate)
	{
		return formatDate(new Date(lDate), "");
	}

	public static String formatTimes(long lDate, String level)
	{
		String dateStr = "";
		int days = 0;
		int hours = 0;
		int minutes = 0;
		long timesHour = 0L;
		long timesMinute = 0L;
		long currentTime = new Date().getTime();
		if (currentTime >= lDate)
		{
			long times = currentTime - lDate;
			days = (int) (times / 86400000L);
			timesHour = times % 86400000L;
			hours = (int) (timesHour / 3600000L);
			timesMinute = timesHour % 3600000L;
			minutes = (int) (timesMinute / 60000L);
			if ("".equals(level))
			{
				if ((days == 0) && (hours == 0) && (minutes == 0))
				{
					dateStr = "刚刚";
				}
				else if ((days != 0) && (hours == 0) && (minutes == 0))
				{
					dateStr = String.valueOf(days) + "天前";
				}
				else if ((days == 0) && (hours != 0) && (minutes == 0))
				{
					dateStr = String.valueOf(hours) + "小时前";
				}
				else if ((days == 0) && (hours == 0) && (minutes != 0))
				{
					dateStr = String.valueOf(minutes) + "分钟前";
				}
				else if ((days != 0) && (hours == 0) && (minutes != 0))
				{
					dateStr = String.valueOf(days) + "天前";
				}
				else if ((days != 0) && (hours != 0) && (minutes == 0))
				{
					dateStr = String.valueOf(days) + "天"
							+ String.valueOf(hours) + "小时前";
				}
				else if ((days == 0) && (hours != 0) && (minutes != 0))
				{
					dateStr = String.valueOf(hours) + "小时"
							+ String.valueOf(minutes) + "分钟前";
				}
				else
				{
					dateStr = String.valueOf(days) + "天"
							+ String.valueOf(hours) + "小时前";
				}
			}
			else if ("1".equals(level))
				if ((days == 0) && (hours == 0) && (minutes == 0))
				{
					dateStr = "刚刚";
				}
				else if ((days != 0) && (hours == 0) && (minutes == 0))
				{
					dateStr = String.valueOf(days) + "天前";
				}
				else if ((days == 0) && (hours != 0) && (minutes == 0))
				{
					dateStr = String.valueOf(hours) + "小时前";
				}
				else if ((days == 0) && (hours == 0) && (minutes != 0))
				{
					dateStr = String.valueOf(minutes) + "分钟前";
				}
				else if ((days != 0) && (hours == 0) && (minutes != 0))
				{
					dateStr = String.valueOf(days) + "天前";
				}
				else if ((days != 0) && (hours != 0) && (minutes == 0))
				{
					dateStr = String.valueOf(days) + "天前";
				}
				else if ((days == 0) && (hours != 0) && (minutes != 0))
				{
					dateStr = String.valueOf(hours) + "小时前";
				}
				else dateStr = String.valueOf(days) + "天前";
		}
		else
		{
			dateStr = "刚刚";
		}

		return dateStr;
	}

	public String formatTimes(Date date)
	{
		long lDate = date.getTime();
		return formatTimes(lDate, "");
	}

	public static String formatJustDate(long lDate)
	{
		return formatDate(new Date(lDate), "yyyy-MM-dd");
	}

	public static String formatDate(Date date, String sFormat)
	{
		if (date == null)
			return "";
		
		if ((sFormat == null) || (sFormat.trim().equals("")))
		{
			sFormat = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat df = new SimpleDateFormat(sFormat);

		return df.format(date);
	}
	
	public static String ajaxEncode (String str, String encode)
	{
		String encodeStr = "";
		try {
			encodeStr = java.net.URLDecoder.decode(str,encode);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} 
		return encodeStr;
	}
	
	/**
	 * 
	 * <p>Description:判断list是否为空</p>
	 * @param list
	 * @return
	 * @date 2016年4月25日 下午3:17:10
	 */
    public static <T> boolean isEmpty(List<T> list)
    {
        if (list == null || list.size() == 0)
            return true;
        return false;
    }
    
    /**
     * 对字符串md5加密
     *
     * @param str
     * @return
     */
    public static String genMD5(String str) 
    {
		try
		{
			// 生成一个MD5加密计算摘要
			MessageDigest md = MessageDigest.getInstance("MD5");
			// 计算md5函数
			md.update(str.getBytes());
			// digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
			// BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
			return new BigInteger(1, md.digest()).toString(16);
		}
		catch (Exception e)
		{
			logger.error("MD5加密出现错误：" + str);
			return "";
		}
    }
    
	/**
	 * 生成UUID
	 *
	 * @return
	 */
	public static String genUUID()
	{
		String uuid = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
		return uuid;
	}

	/**
	 * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
	 * 
	 * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
	 * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
	 * 
	 * 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130,
	 * 192.168.1.100
	 * 
	 * 用户真实IP为： 192.168.1.110
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddress(HttpServletRequest request)
	{
		String ip = request.getHeader("x-forwarded-for");
		if (Tools.isTrimEmpty(ip) || "unknown".equalsIgnoreCase(ip))
			ip = request.getHeader("Proxy-Client-IP");
		if (Tools.isTrimEmpty(ip) || "unknown".equalsIgnoreCase(ip))
			ip = request.getHeader("WL-Proxy-Client-IP");
		if (Tools.isTrimEmpty(ip) || "unknown".equalsIgnoreCase(ip))
			ip = request.getHeader("HTTP_CLIENT_IP");
		if (Tools.isTrimEmpty(ip) || "unknown".equalsIgnoreCase(ip))
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		if (Tools.isTrimEmpty(ip) || "unknown".equalsIgnoreCase(ip))
			ip = request.getRemoteAddr();
		return ip;
	}
	
    /**
     * 根据键值获取数据
     *
     * @param data	数据map
     * @param key	键值
     * 
     * @return
     */
    public static String getStringFromMap(Map<String, Object> data, String key)
    {
        String result = "";
        if (data == null || data.isEmpty() || !data.containsKey(key))
        	return result;
        
        result = data.get(key).toString();
        return result;
    }
    
    /**
     * 根据键值获取数据
     *
     * @param data	数据map
     * @param key	键值
     * 
     * @return
     */
    public static int getIntFromMap(Map<String, Object> data, String key)
    {
        String result = getStringFromMap(data, key);
        if (!isEmpty(result))
        	return genInt(result);
        else
        	return 0;
    }
    
    /**
     * 根据键值获取数据
     *
     * @param data	数据map
     * @param key	键值
     * 
     * @return
     */
    public static long getLongFromMap(Map<String, Object> data, String key)
    {
        String result = getStringFromMap(data, key);
        if (!isEmpty(result))
        	return genLong(result);
        else
        	return 0l;
    }
    
    /**
     * 根据键值获取数据
     *
     * @param data	数据map
     * @param key	键值
     * 
     * @return
     */
    public static double getDoubleFromMap(Map<String, Object> data, String key)
    {
        String result = getStringFromMap(data, key);
        if (!isEmpty(result))
        	return genDouble(result);
        else
        	return 0d;
    }
    
    private static final String charStr = "0123456789";
	
	/**
	 * 生成随机码
	 *
	 * @param length	需要生成几位
	 * 
	 * @return	生成的随机码
	 */
	public static String genRandomCode(int length)
	{
		String result= "";
		for (int i = 0; i < length; i++)
		{
			result += charStr.charAt((int)(Math.random() * charStr.length()));
		}
		
		return result;
	}
	
	/**
	 * 拿到分页的总页数
	 * @param totalNum	总记录数
	 * @param pageSize	每页几条数据
	 * @return			拿到分页的总页数
	 * add by zhuweifeng update at 2012-03-22
	 */
	public static int totalPage(int totalNum, int pageSize)
	{
		int pageCount = 0;
		if (totalNum == 0 || pageSize == 0)
			return pageCount;
		if (totalNum <= 0 || pageSize <= 0)
			return pageCount;
		
		if((totalNum % pageSize) == 0)
			pageCount = (totalNum / pageSize);
		else
			pageCount = (totalNum / pageSize)+1;
		return pageCount;
	}
	
}
